﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace LifeKostyuk
{
    class Life
    {

        public void CalculateLife(string fileName, int numberOfIterations)
        {
            bool[,] universe = LoadFromFile(fileName);

            CreateDirectoryIfNotExist(fileName);

            for (int i = 0; i < numberOfIterations; i++)
            {
                universe = MakeIteration(universe);
                viewOnDisplay(convertToList(universe));  
            //    SaveToFile(GetFileName(fileName, i), convertToList(universe));
            }
        }

        public void CreateDirectoryIfNotExist(string baseFileName)
        {
           
            string path = baseFileName.Substring(0, baseFileName.LastIndexOf(@"\"))+@"\Life";
           
            if (Directory.Exists(path))
            {
                foreach (string s in Directory.GetFiles(path))
                    File.Delete(s);
                Directory.Delete(path);
            }
                        
                Directory.CreateDirectory(path);
                   

        }

        public string GetFileName(string basefilename, int i)
        {
           string iterationFileName = basefilename.Substring(0, basefilename.LastIndexOf(@"\"))+@"\Life\"+(i+1)+@".txt";
           return iterationFileName;
        }

        public int[] getIndex(int i, int j, int maxI, int maxJ)
        {
            int[] indexArray = new int[16];
            int count = 0;
            for (int a = -1; a < 2; a++)
            {
                for (int b = -1; b < 2; b++)
                {
                    if (a == 0 && b == 0)
                        continue;
                    
                    indexArray[count] = i+a;
                    indexArray[count + 1] = j+b;
                    if (i+a == -1) indexArray[count] = maxI;
                    if (j+b== -1) indexArray[count + 1] = maxJ;
                    if (i+a== maxI + 1) indexArray[count] = 0;
                    if (j+b== maxJ + 1) indexArray[count + 1] = 0;
                    count+=2;
                }
            }
            
            return indexArray;
        }

        
        public bool[,] MakeIteration(bool[,] universe)
        {
            bool[,] newUniverse = new bool[universe.GetLength(0), universe.GetLength(1)];
            int[] index = new int [16];
            int count=0;
            for (int i = 0; i < universe.GetLength(0); i++)
            {
                for (int j = 0; j < universe.GetLength(1); j++)
                {
                    index =  getIndex(i, j, universe.GetLength(0)-1, universe.GetLength(1)-1);
                    for (int k=0; k<16; k+=2)
                    {
                        if (universe[index[k], index[k + 1]] == true)
                            count++;   
                    }

                    if (count > 3)
                    {
                        newUniverse[i, j] = false;
                        count = 0;
                        continue;
                    }
                    if (count < 2)
                    {
                        newUniverse[i, j] = false;
                        count = 0;
                        continue;
                    }
                    if (universe[i, j] == false && count == 3)
                    {
                        newUniverse[i, j] = true;
                        count = 0;
                        continue;
                    }
                    newUniverse[i, j] = universe[i, j];

                    count = 0;

                }
            }
                return newUniverse;
        }

        public bool[,] LoadFromFile(string fileName)
        {
            List<string> rows = new List<string>();
            using (FileStream fs = File.OpenRead(fileName))
            {
                
                using (StreamReader sr = new StreamReader(fs))
                {
                    string line;
                    while ((line = sr.ReadLine()) != null)
                    {
                        rows.Add(line);
                    }
                }

            }
            bool[,] boolArray = new bool[ rows.Count, rows[0].Length];
            int i = 0, j = 0;
            foreach (string s in rows)
            {
                j = 0;
                foreach (char c in s)
                {
                    if (c == '-')
                        boolArray[i, j] = false;
                    else boolArray[i, j] = true;
                    j++;
                }
                i++;
            }
            return(boolArray);

        }

        public void viewOnDisplay(List<string> stringsList)
        {
            Console.Clear();
            foreach (string s in stringsList)
                Console.WriteLine(s);
            Thread.Sleep(100);
            
            //Console.ReadKey();
        }

        public List<string> convertToList(bool[,] universe)
        {
            List<string> stringsList = new List<string>();
            for (int i = 0; i < universe.GetLength(0); i++)
            {
                string str = string.Empty;
                for (int j = 0; j < universe.GetLength(1); j++)
                {
                    if (universe[i, j] == false)
                        str += '-';
                    else str += 'x';
                }
                stringsList.Add(str);
            }
            return stringsList;
        }

        public void SaveToFile(string fileName, List<string> stringsList) 
        {
            
            using (FileStream fs = File.Create(fileName)) 
            {
                using (StreamWriter sw = new StreamWriter(fs))
                {
                    foreach (string s in stringsList)
                        sw.WriteLine(s);
                }
            }
        }
    }
}
